home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_08_03
/
8n03115a
< prev
next >
Wrap
Text File
|
1990-03-18
|
12KB
|
349 lines
#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "string.h"
#include "graph.fd"
#include "halo.h"
#define OK 1
#define FAIL 0
#define TRUE 1
#define FALSE 0
#define CMD_DELIMITER " \t\n"
#define VAL_DELIMITER ",\n"
#define TICK_WIDTH 0.025
#define SQRT_2 1.414213562
char *cmd_strs[] = {"DATA","COLORS","MODE","ATTRIBUTES","SCALE","LEGEND",
"FONT","TITLES","DEVICE","PRINTER","COMMENT","END" };
enum cmd_vals { C_DATA, C_COLORS, C_MODE, C_ATTRIBUTES, C_SCALE, C_LEGEND,
C_FONT, C_TITLES, C_DEVICE, C_PRINTER, C_COMMENT, C_END };
#define NUM_CMD_VALS ((int)C_END)
union udata {
float fdata[64]; /* Numeric data for commands (e.g. COLORS) */
char cdata[16][16]; /* String data for commands (e.g. LEGEND) */
};
typedef struct cmd_data_type {
union udata d; /* Commands data is string or numeric */
int count; /* Number of data items found in command */
} cmd_data_type, *cmd_data_type_p;
typedef struct { /* HALO '88 specific global data */
char *device; /* Name of HALO screen device driver */
char *font; /* Name of HALO stroke font file */
float x1,y1,x2,y2; /* World coordinates rectangle values */
int degree_mode; /* if true use degrees, else radians */
int lnstyle; /* Line style, 1 <= lnstyle <= 10 */
int lnwidth; /* Line thickness in pixels, always odd */
int maxcolor; /* Number of colors supported by device */
int mode; /* Device dependent graphics mode */
} halo_type;
typedef struct {
float start_x, start_y; /* Bottom corner of graph draw area */
float end_x, end_y; /* Upper corner of graph draw area */
float scale_min, scale_max; /* Y-Axis min and max values */
int num_points; /* Number of points in DATA file */
int num_ticks; /* Number of ticks on the Y-Axis */
int num_colors; /* Number of user-supplied colors */
char *legend; /* User-supplied LEGEND */
} graph_type;
cmd_data_type cmd_data[NUM_CMD_VALS];
halo_type halo;
graph_type graph;
main(argc,argv)
int argc;
char **argv;
{
char inp_line[128];
FILE *infile;
if (argc>1) { /* First argv should be input data file */
if ((infile=fopen(argv[1],"r")) == NULL) {
fprintf(stderr,"Error: can't open %s\n",argv[1]);
exit(-1);
}
}
else { /* no data file was given */
fprintf(stderr,"Usage: graph inputfile\n");
exit(-1);
}
memset(cmd_data, 0, sizeof(cmd_data));
while(fgets(inp_line,sizeof(inp_line)-1,infile) != NULL)
process_graphics_cmd_line(inp_line);
fclose(infile);
setup_halo_globals(); /* Capture relevant parameters */
setup_graph_globals();
draw_bar_graph(); /* Draw the actual graph */
deltcur(); /* Remove text "_" cursor */
getch();
print_graph(); /* Print graph if requested */
closegraphics(); /* Close out all devices */
return OK;
}
int process_graphics_cmd_line(inp_line)
char *inp_line;
{
char input[128];
char *cmd_keywd;
int found = FALSE;
int cmd_val;
strcpy(input,inp_line);
if ((cmd_keywd=strtok(input,CMD_DELIMITER)) == NULL) {
fprintf(stderr,"Unable to parse to command <%s>\n",inp_line);
return FAIL;
}
for (cmd_val=0; cmd_val<=NUM_CMD_VALS; cmd_val++)
if (stricmp(cmd_strs[cmd_val],cmd_keywd)==0) {
found = TRUE;
break;
}
if (!found) {
fprintf(stderr,"Keyword <%s> not recognized.\n",cmd_keywd);
return FAIL;
}
if (cmd_val <= C_SCALE)
parse_delimited_number_list(&cmd_data[cmd_val]);
else
parse_delimited_string_list(&cmd_data[cmd_val]);
return OK;
}
void parse_delimited_number_list(data_p)
cmd_data_type *data_p;
{
int i;
char *cmd_data;
i = data_p->count;
while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
data_p->d.fdata[i++] = (float) atof(cmd_data);
data_p->count = i;
}
void parse_delimited_string_list(data_p)
cmd_data_type_p data_p;
{
int i;
char *cmd_data;
i = data_p->count;
while ((cmd_data=strtok(NULL,VAL_DELIMITER)) != NULL)
strcpy(data_p->d.cdata[i++],cmd_data);
data_p->count = i;
}
void setup_halo_globals()
{
if (cmd_data[C_DEVICE].count) /* Was there a DEVICE command? */
halo.device = cmd_data[C_DEVICE].d.cdata[0];
else /* No, use the default */
halo.device = "HALOIBMG.DEV";
printf("using device <%s>, press any key to start:\n",halo.device);
getch();
setdev(halo.device); /* Initialize the graphics device */
halo.mode = (int) cmd_data[C_MODE].d.fdata[0];
initgraphics(&halo.mode); /* Clear screen in given mode */
halo.degree_mode = 1;
setdegree(&halo.degree_mode); /* Use degrees, not radians */
halo.x1 = (float) 0.0; halo.y1 = (float) 0.0;
halo.x2 = (float) 1.0; halo.y2 = (float) 1.0;
setworld(&halo.x1,&halo.y1,&halo.x2,&halo.y2); /* World rectangle */
inqcrange(&halo.maxcolor ); /* Find max color value */
halo.lnwidth = 1;
setlnwidth(&halo.lnwidth) ; /* Line width is 1 pixel */
halo.lnstyle = 1;
setlnstyle(&halo.lnstyle); /* Line style is solid */
setcolor(&halo.maxcolor); /* Max screen color is usually white */
if (cmd_data[C_FONT].count) /* Was there a FONT command? */
halo.font = cmd_data[C_FONT].d.cdata[0];
else /* No, use the default */
halo.font = "HALO104.FNT";
setfont(halo.font); /* Load font from disk file */
setstclr(&halo.maxcolor,&halo.maxcolor) ; /* Set stroke text color */
}
void setup_graph_globals()
{
float *data_ptr;
int i;
/* This rectangle is the active drawing area of the global window */
graph.start_x = (float) 0.1; graph.end_x = (float) 0.9;
graph.start_y = (float) 0.15; graph.end_y = (float) 0.88;
graph.num_ticks = 10;
graph.num_points = cmd_data[C_DATA].count;
graph.num_colors = cmd_data[C_COLORS].count;
graph.legend = cmd_data[C_LEGEND].d.cdata[0];
if (cmd_data[C_SCALE].count) { /* User supplied SCALE boundaries */
graph.scale_min = cmd_data[C_SCALE].d.fdata[0];
graph.scale_max = cmd_data[C_SCALE].d.fdata[1];
}
else { /* No SCALE bounds, use min and max data values for SCALE */
graph.scale_min = (float) 0.0;
graph.scale_max = (float) 0.0;
data_ptr = cmd_data[C_DATA].d.fdata;
for (i=0; i < graph.num_points; i++, data_ptr++) {
if (graph.scale_min > *data_ptr)
graph.scale_min = *data_ptr; /* New minimum data point */
if (graph.scale_max < *data_ptr)
graph.scale_max = *data_ptr; /* New maximum data point */
}
}
}
void draw_axes(bar_width)
double bar_width;
{
int i;
float tick_interval; /* Distance between Y-Axis ticks */
float axis_interval; /* Y-Axis tick value in scale units */
float height = (float) 0.10; /* Stroke text height */
float angle = (float) 45.0; /* Stroke text drawing angle */
float asp = (float) 1.0; /* Stroke text aspect ratio */
int path = 0; /* Stroke text path */
float text_height; /* Inquired height of text string */
float text_width; /* Inquired width of text String */
float offse; /* Offset for descenders */
float x_val, y_val; /* General-purpose registers */
char